/*
 *@author Sayes Lucero, Alfredo Andrès Lu:66604
 * @author Diego Ghilardi Lu: 51782
 */
package Alexico;

/**
 * La clase analizadorLex es la encargada de solicitar caracteres a
 * {@link lectorBuffer} que leerá del archivo fuente. Luego de procesar el
 * caracter acutal solicita caracteres hasta armar un nuevo Token o alcanzar
 * un error léxico en el archivo fuente. El error léxico es informado mediante
 * excepción personalizada
 * @author Sayes Lucero, Alfredo Andrès Lu:66604
 * @author Diego Ghilardi Lu: 51782
 */
public class analizadorLex {

    private lectorBuffer buffer;
    private token Token;
    private String lexema;
    private int estado = 0;
    private boolean seguir = true;
    private boolean lei_adelantado = false;
    private String str_carac_actual = "";
    private String str_carac_adelantado = "";
    private estados tablaEstados;
    private boolean errorLectura = false;
    private palabrasEspeciales palabrasEspeciales;
    private int num_linea_actual = 0;
    private int num_nueva_linea = 0;
    private boolean hubo_salto_linea;
    private int linea_inicio_comentario = 0;
    private String caracterExtendido = "";

    /**
     * El constructor de la clase crea una nueva instancia de la clase lectorBuffer
     * a la cual se le pasa como parámetro el parámatro del constructor. El contructor
     * tambien crea la tabla de tokens y tabla de palabras prohibidas
     * @param file String que representa el nombre de archivo. La ruta completa
     */
    public analizadorLex(String file) {
        buffer = new lectorBuffer(file);
        errorLectura = buffer.isErrorLectura();
        if (!errorLectura) {
            tablaEstados = new estados();
            palabrasEspeciales = new palabrasEspeciales();
        }
    }

    /**
     * Al momento de crear el lectorbuffer se puede consultar el valor de verdad
     * si existió un error o no.
     * Este valor booleano se obtiene mediante la solicitud de servicio de éste método
     * @return boolean True:existió error False: no existio error.
     */
    public boolean isErrorLectura() {
        return errorLectura;
    }

    /**
     *Este método retorna true en caso de que el string pasado como parámetro
     * sea una letra o "_", false en caso contrario. Ignora si es mayúscula o minúscula.
     *@param str String a consultar el valor de verdad de si es o no una letra
     *@return boolean
     */
    private boolean isletter(String str) {
        boolean es = false;
        if (str.equalsIgnoreCase("a") || str.equalsIgnoreCase("b") || str.equalsIgnoreCase("c")
                || str.equalsIgnoreCase("d") || str.equalsIgnoreCase("e") || str.equalsIgnoreCase("f")
                || str.equalsIgnoreCase("g") || str.equalsIgnoreCase("h") || str.equalsIgnoreCase("i")
                || str.equalsIgnoreCase("j") || str.equalsIgnoreCase("k") || str.equalsIgnoreCase("l")
                || str.equalsIgnoreCase("m") || str.equalsIgnoreCase("n") || str.equalsIgnoreCase("o")
                || str.equalsIgnoreCase("p") || str.equalsIgnoreCase("q") || str.equalsIgnoreCase("r")
                || str.equalsIgnoreCase("s") || str.equalsIgnoreCase("t") || str.equalsIgnoreCase("u")
                || str.equalsIgnoreCase("v") || str.equalsIgnoreCase("w") || str.equalsIgnoreCase("x")
                || str.equalsIgnoreCase("y") || str.equalsIgnoreCase("z") || str.equals("_")) {
            es = true;
        }
        return es;
    }

    /*
     * Esta funciòn, dado un string, retorna true si el mismo es un digito,
     * false en caso contrario
     */
    private boolean isdigit(String str) {
        boolean es = false;
        if (str.equals("0") || str.equals("1") || str.equals("2") || str.equals("3")
                || str.equals("4") || str.equals("5") || str.equals("6") || str.equals("7")
                || str.equals("8") || str.equals("9")) {
            es = true;
        }
        return es;
    }

    private boolean perteneceAlfabeto(String c) {
        boolean pertenece = false;

        int ascii;
        ascii = c.charAt(0);
        if (ascii >= 32 && ascii <= 126) {
            pertenece = true;
        }
        return pertenece;
    }

    /**
     * Este método itera solicitando caracteres al {@link lectorBuffer} y de acuerdo
     * al estado actual y al caracter leido, se obtiene consultando el
     * objeto instancia de la clase {@link estados} un nuevo estado.
     * Esta iteración continuará hasta encontrar un token perteneciente al lenguaje
     * Minijava-DECAF o alcanzando un error léxico en el programa fuente.
     *@throws Exception errorLexico que hereda de Exception
     *@see errorLexico
     *@see lectorBuffer
     *@see estados
     *@see palabrasEspeciales
     *@return Token
     */
    public token getToken() throws Exception {
        int nro = 0;
        String nombreToken = null;
        String tokenProhibido = null;
        String msg = "";
        String motivo = " Causa: ";
        int nro_linea_aux = 0;
        char a;
        estado = 0;
        seguir = true;
        lexema = "";
        Token = null;
        str_carac_actual = "";
        token pesos = null;

        if (this.caracterExtendido.equals("$")) {
            Token = new token("$");
            Token.setNombre("PESOS");
            Token.setNumLinea(num_linea_actual);
            seguir = false;
        }
        while (seguir) {
            if (lei_adelantado) {
                str_carac_actual = str_carac_adelantado;
                lei_adelantado = false;
            } else {
                str_carac_actual = buffer.leerCaracter();
                num_nueva_linea = buffer.getNum_linea();
                if (num_linea_actual < num_nueva_linea) {
                    hubo_salto_linea = true;
                    num_linea_actual = num_nueva_linea;
                } else {
                    hubo_salto_linea = false;
                }
                if (str_carac_actual != null && !perteneceAlfabeto(str_carac_actual)) {
                    nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                    msg = errorLexico.construirError(10, nro_linea_aux, str_carac_actual);
                    throw new errorLexico(msg);
                }
                /*if(str_carac_actual==null) //CONTROLAR!!!!
                { //Se llego a fin de archivo    
                Token=new token("$");
                Token.setNombre("$");
                Token.setNumLinea(num_linea_actual);
                seguir=false;
                }*/
            }
            if (str_carac_actual == null) //CONTROLAR!!!!
            { //Se llego a fin de archivo    
                this.caracterExtendido = "$";
            }

            switch (estado) {
                case 0: {
                    if (str_carac_actual == null) {
                        Token = new token("$");
                        Token.setNombre("PESOS");
                        Token.setNumLinea(num_linea_actual);
                        seguir = false;
                    } else {
                        if ((str_carac_actual.equals("#")) || (str_carac_actual.equals(":"))
                                || (str_carac_actual.equals("?")) || (str_carac_actual.equals("["))
                                || (str_carac_actual.equals("]")) || (str_carac_actual.equals("^"))
                                || (str_carac_actual.equals("~")) || (str_carac_actual.equals("\\"))
                                || (str_carac_actual.equals("@") || (str_carac_actual.equals("$")))) {
                            if (num_linea_actual < num_nueva_linea) {
                                num_linea_actual = num_nueva_linea;
                                nro = num_linea_actual - this.buffer.getCant_saltos();
                            } else {
                                nro = num_linea_actual;
                            }
                            msg = errorLexico.construirError(1, nro, str_carac_actual);
                            throw new errorLexico(msg);
                        }
                        if (!str_carac_actual.equals(" ")) {
                            lexema = lexema.concat(str_carac_actual);
                        }
                        estado = tablaEstados.transicion(estado, str_carac_actual);

                    }
                    break;
                }
                case 1: {
                    if (str_carac_actual != null && !hubo_salto_linea) {

                        /*bloque que controla errores lexicales*/
                        if ((str_carac_actual.equals("\'"))
                                || (str_carac_actual.equals("\""))
                                || (str_carac_actual.equals("{"))
                                || (str_carac_actual.equals("}"))
                                || (str_carac_actual.equals("#"))
                                || (str_carac_actual.equals(":"))
                                || (str_carac_actual.equals("?"))
                                || (str_carac_actual.equals("["))
                                || (str_carac_actual.equals("]"))
                                || (str_carac_actual.equals("^"))
                                || (str_carac_actual.equals("~"))
                                || (str_carac_actual.equals("\\"))
                                || (str_carac_actual.equals("."))
                                || isletter(str_carac_actual)) {
                            nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                            msg = errorLexico.construirError(2, nro_linea_aux, lexema.concat(str_carac_actual));
                            throw new errorLexico(msg);
                        }
                        /*Fin de bloque que controla errores lexicales*/
                        if (this.isdigit(str_carac_actual)) {
                            lexema = lexema.concat(str_carac_actual);
                        } else {
                            Token = new token(lexema);
                            nombreToken = palabrasEspeciales.obtenerNomToken("num");
                            Token.setNombre(nombreToken);
                            Token.setNumLinea(buffer.getNum_linea());
                            lei_adelantado = true;
                            str_carac_adelantado = str_carac_actual;
                            seguir = false;
                        }
                    }//fin de bloque de str_carac_actual_!= null o salto de linea
                    else/* llegue a fin de archivo o fin de  linea pero tenia un token valido*/ {
                        if (hubo_salto_linea) {
                            lei_adelantado = true;
                            str_carac_adelantado = str_carac_actual;
                            nro = num_linea_actual - this.buffer.getCant_saltos();
                        } else {
                            nro = num_linea_actual;
                        }
                        Token = new token(lexema);
                        nombreToken = palabrasEspeciales.obtenerNomToken("num");
                        
                        Token.setNombre(nombreToken);
                        Token.setNumLinea(nro);
                        seguir = false;
                    }
                    break;
                }
                case 2: {
                    /*inicio bloque de control de excepciones*/
                    if (str_carac_actual == null || hubo_salto_linea || str_carac_actual.equals("'")) {
                        nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                        msg = errorLexico.construirError(3, nro_linea_aux, lexema.concat(str_carac_actual));
                        throw new errorLexico(msg);
                    }
                    /*Fin bloque de control de excepciones*/

                    //25/08/2012:12:45  hay que reconocer char = '\\'
                            /*
                    if( !str_carac_actual.equals("\\"))
                    {
                    lexema=lexema.concat(str_carac_actual);
                    }*/
                    lexema = lexema.concat(str_carac_actual);
                    estado = tablaEstados.transicion(estado, str_carac_actual);
                    break;
                }
                case 3: {
                    /*inicio bloque de control de excepciones*/
                    if (str_carac_actual == null || hubo_salto_linea) {
                        nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                        msg = errorLexico.construirError(3, nro_linea_aux, "Hay salto de linea o caracter sin cerrar en: " + lexema);
                        throw new errorLexico(msg);
                    }
                    /*Fin bloque de control de excepciones*/
                    /* if( str_carac_actual.equals("t")  || str_carac_actual.equals("n") )
                    {
                    lexema=lexema.concat("\\");
                    }
                     */

                    lexema = lexema.concat(str_carac_actual);
                    estado = tablaEstados.transicion(estado, str_carac_actual);
                    break;
                }
                case 4: {
                    /*inicio bloque de control de excepciones*/
                    if (str_carac_actual == null || hubo_salto_linea || !(str_carac_actual.equals("'"))) {
                        nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                        msg = errorLexico.construirError(3, nro_linea_aux, "Hay salto de linea o caracter sin cerrar en:  " + lexema.concat(str_carac_actual));
                        throw new errorLexico(msg);
                    }
                    /*Fin bloque de control de excepciones*/
                    lexema = lexema.concat(str_carac_actual);
                    estado = tablaEstados.transicion(estado, str_carac_actual);
                    break;
                }
                case 5: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken("charLiteral"));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 6: {
                    /*Inicio bloque de control de excepciones*/
                    if (str_carac_actual == null || hubo_salto_linea) {
                        nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                        msg = errorLexico.construirError(4, nro_linea_aux, lexema);
                        throw new errorLexico(msg);
                    }
                    /*Fin bloque de control de excepciones*/
                    if (!str_carac_actual.equals("\\")) {
                        lexema = lexema.concat(str_carac_actual);
                    }
                    estado = tablaEstados.transicion(estado, str_carac_actual);
                    break;
                }
                case 7: {
                    /*Inicio bloque de control de excepciones*/
                    if (str_carac_actual == null || hubo_salto_linea
                            || (!(str_carac_actual.equals("'"))
                            && !(str_carac_actual.equals("\\"))
                            && !(str_carac_actual.equals("\"")))) {
                        nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                        msg = errorLexico.construirError(3, nro_linea_aux, "Hay salto de linea o caracter sin cerrar en:  " + lexema);
                        throw new errorLexico(msg);
                    }
                    /*Fin bloque de control de excepciones*/
                    lexema = lexema.concat(str_carac_actual);
                    estado = tablaEstados.transicion(estado, str_carac_actual);
                    break;
                }
                case 8: {
                    /*Inicio bloque de control de excepciones*/
                    if (str_carac_actual == null || hubo_salto_linea) {
                        nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                        msg = errorLexico.construirError(4, nro_linea_aux, "String sin cerrar en: " + lexema);
                        throw new errorLexico(msg);
                    }
                    /*Fin bloque de control de excepciones*/
                    if (!str_carac_actual.equals("\\")) {
                        lexema = lexema.concat(str_carac_actual);
                    }
                    estado = tablaEstados.transicion(estado, str_carac_actual);
                    break;
                }
                case 9: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken("stringLiteral"));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 10: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 11: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 12: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 13: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 14: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 15: {
                    /*Inicio bloque de control de excepciones*/
                    if (str_carac_actual == null || hubo_salto_linea || !(str_carac_actual.equals("&"))) {
                        nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                        msg = errorLexico.construirError(5, nro_linea_aux);
                        throw new errorLexico(msg);
                    }
                    /*Fin bloque de control de excepciones*/
                    lexema = lexema.concat(str_carac_actual);
                    estado = tablaEstados.transicion(estado, str_carac_actual);
                    break;
                }
                case 16: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 17: {
                    if (str_carac_actual != null) {
                        if (str_carac_actual.equals("="))//me voy al S18
                        {
                            if (!hubo_salto_linea) {
                                lexema = lexema.concat(str_carac_actual);
                                estado = tablaEstados.transicion(estado, str_carac_actual);
                            } else {
                                Token = new token(lexema);
                                Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                                nro = num_linea_actual - this.buffer.getCant_saltos();
                                Token.setNumLinea(nro);
                                lei_adelantado = true;
                                str_carac_adelantado = str_carac_actual;
                                seguir = false;
                            }

                        }//if
                        else //str_caracter_actual !="=", es asignacion
                        {
                            if (hubo_salto_linea) {
                                nro = num_linea_actual - this.buffer.getCant_saltos();
                            } else {
                                nro = num_linea_actual;
                            }
                            Token = new token(lexema);
                            Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                            Token.setNumLinea(nro);
                            lei_adelantado = true;
                            str_carac_adelantado = str_carac_actual;
                            seguir = false;
                        }//else
                    } else {
                        if (hubo_salto_linea) {
                            nro = num_linea_actual - this.buffer.getCant_saltos();
                        } else {
                            nro = num_linea_actual;
                        }
                        Token = new token(lexema);
                        Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                        Token.setNumLinea(nro);
                        seguir = false;
                    }
                    break;
                }
                case 18: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 19: {
                    if (str_carac_actual != null) {
                        if (str_carac_actual.equals("=")) {
                            if (!hubo_salto_linea) {
                                lexema = lexema.concat(str_carac_actual);
                                estado = tablaEstados.transicion(estado, str_carac_actual);
                            } else {
                                if (hubo_salto_linea) {
                                    nro = num_linea_actual - this.buffer.getCant_saltos();
                                } else {
                                    nro = num_linea_actual;
                                }
                                Token = new token(lexema);
                                Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                                Token.setNumLinea(nro);
                                lei_adelantado = true;
                                str_carac_adelantado = str_carac_actual;
                                seguir = false;
                            }
                        }//if
                        else //str_carac_actual != "=", ie, menor
                        {
                            if (hubo_salto_linea) {
                                nro = num_linea_actual - this.buffer.getCant_saltos();
                            } else {
                                nro = num_linea_actual;
                            }
                            lei_adelantado = true;
                            str_carac_adelantado = str_carac_actual;
                            Token = new token(lexema);
                            Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                            Token.setNumLinea(nro);
                            seguir = false;
                        }//else
                    } else {
                        if (hubo_salto_linea) {
                            nro = num_linea_actual - this.buffer.getCant_saltos();
                        } else {
                            nro = num_linea_actual;
                        }
                        Token = new token(lexema);
                        Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                        Token.setNumLinea(nro);
                        seguir = false;
                    }
                    break;
                }
                case 20: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 21: {
                    if (str_carac_actual != null) {
                        if (str_carac_actual.equals("=")) {
                            if (!hubo_salto_linea) {
                                lexema = lexema.concat(str_carac_actual);
                                estado = tablaEstados.transicion(estado, str_carac_actual);
                            } else {
                                if (hubo_salto_linea) {
                                    nro = num_linea_actual - this.buffer.getCant_saltos();
                                } else {
                                    nro = num_linea_actual;
                                }
                                Token = new token(lexema);
                                Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                                Token.setNumLinea(nro);
                                lei_adelantado = true;
                                str_carac_adelantado = str_carac_actual;
                                seguir = false;
                            }
                        }//if
                        else //str_carac_actual != "=", ie, menor
                        {
                            if (hubo_salto_linea) {
                                nro = num_linea_actual - this.buffer.getCant_saltos();
                            } else {
                                nro = num_linea_actual;
                            }
                            lei_adelantado = true;
                            str_carac_adelantado = str_carac_actual;
                            Token = new token(lexema);
                            Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                            Token.setNumLinea(nro);
                            seguir = false;
                        }//else
                    } else {
                        if (hubo_salto_linea) {
                            nro = num_linea_actual - this.buffer.getCant_saltos();
                        } else {
                            nro = num_linea_actual;
                        }
                        Token = new token(lexema);
                        Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                        Token.setNumLinea(nro);
                        seguir = false;
                    }
                    break;
                }
                case 22: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 23: {
                    if (str_carac_actual != null) {
                        if (str_carac_actual.equals("=")) {
                            if (!hubo_salto_linea) {
                                lexema = lexema.concat(str_carac_actual);
                                estado = tablaEstados.transicion(estado, str_carac_actual);
                            } else {

                                nro = num_linea_actual - this.buffer.getCant_saltos();
                                Token = new token(lexema);
                                Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                                Token.setNumLinea(nro);
                                lei_adelantado = true;
                                str_carac_adelantado = str_carac_actual;
                                seguir = false;
                            }
                        }//if
                        else //str_carac_actual != "=", ie, menor
                        {
                            if (hubo_salto_linea) {
                                nro = num_linea_actual - this.buffer.getCant_saltos();
                            } else {
                                nro = num_linea_actual;
                            }
                            lei_adelantado = true;
                            str_carac_adelantado = str_carac_actual;
                            Token = new token(lexema);
                            Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                            Token.setNumLinea(nro);
                            seguir = false;
                        }//else
                    } else {
                        if (hubo_salto_linea) {
                            nro = num_linea_actual - this.buffer.getCant_saltos();
                        } else {
                            nro = num_linea_actual;
                        }
                        Token = new token(lexema);
                        Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                        Token.setNumLinea(nro);
                        seguir = false;
                    }
                    break;
                }
                case 24: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 25: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 26: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 27: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 28: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 29: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 30: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
                case 31: {
                    if (str_carac_actual != null && !hubo_salto_linea) {
                        if (str_carac_actual.equals("\'") || str_carac_actual.equals("\""))/*|| str_carac_actual.equals("}")
                        || str_carac_actual.equals("{"))*/ {
                            nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                            msg = errorLexico.construirError(6, nro_linea_aux, lexema.concat(str_carac_actual));
                            throw new errorLexico(msg);
                        }
                        /*fin de bloque de control de excepciones*/
                        if (!hubo_salto_linea) {
                            if (!this.isdigit(str_carac_actual) && !this.isletter(str_carac_actual)) {
                                if (lexema.equals("num")) {
                                    //num es la cadena 
                                    nombreToken = palabrasEspeciales.obtenerNomToken("");

                                } else {
                                    nombreToken = palabrasEspeciales.obtenerNomToken(lexema);
                                }


                                if (nombreToken == null)//No es reservada
                                {

                                    tokenProhibido = palabrasEspeciales.obtenerPalabraProhibida(lexema);
                                    if (tokenProhibido != null)//Es palabra prohibida
                                    {
                                        nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                                        msg = errorLexico.construirError(9, nro_linea_aux, tokenProhibido);
                                        throw new errorLexico(msg);
                                    } else {
                                        Token = new token(lexema);//es un identificador
                                        Token.setNombre(palabrasEspeciales.obtenerNomToken("0"));
                                    }

                                } else {
                                    Token = new token(lexema);//es RESERVADA
                                    Token.setNombre(nombreToken);
                                }
                                Token.setNumLinea(buffer.getNum_linea());
                                lei_adelantado = true;
                                str_carac_adelantado = str_carac_actual;
                                seguir = false;
                            } else {
                                if (this.isdigit(str_carac_actual) || this.isletter(str_carac_actual)) {
                                    lexema = lexema.concat(str_carac_actual);
                                }

                            }


                        }

                    }//if str_carac_actual!=null && !hubo_salto_linea
                    else {
                        if (!hubo_salto_linea) {
                            lei_adelantado = true;
                            str_carac_adelantado = str_carac_actual;
                            nro = num_linea_actual;// - this.buffer.getCant_saltos();
                        } else {
                            /*correccion*/ nro = num_linea_actual - this.buffer.getCant_saltos();
                        }
                        if (lexema.equals("num")) {
                            //num es la cadena 
                            nombreToken = palabrasEspeciales.obtenerNomToken("");

                        } else {
                            nombreToken = palabrasEspeciales.obtenerNomToken(lexema);
                        }
                        if (nombreToken == null)//No es reservada
                        {
                            tokenProhibido = palabrasEspeciales.obtenerPalabraProhibida(lexema);
                            if (tokenProhibido != null)//Es palabra prohibida
                            {
                                nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                                msg = errorLexico.construirError(9, nro_linea_aux, tokenProhibido);
                                throw new errorLexico(msg);
                            } else {
                                Token = new token(lexema);//es un identificador
                                Token.setNombre(palabrasEspeciales.obtenerNomToken("0"));
                            }

                        } else {
                            Token = new token(lexema);//es RESERVADA
                            Token.setNombre(nombreToken);
                        }
                        Token.setNumLinea(nro);
                        lei_adelantado = true;
                        str_carac_adelantado = str_carac_actual;
                        seguir = false;

                    }

                    break;
                }
                case 32: {
                    if (hubo_salto_linea) {
                        if (str_carac_actual != null) {
                            lei_adelantado = true;
                            str_carac_adelantado = str_carac_actual;
                        }
                        Token = new token(lexema);
                        Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                        Token.setNumLinea(nro);
                        seguir = false;
                    } else {
                        if (str_carac_actual.equals("/")) {
                            estado = this.tablaEstados.transicion(estado, str_carac_actual);
                            this.buffer.consumirLinea();
                            lexema = "";
                            lei_adelantado = false;
                        } else {
                            if (str_carac_actual.equals("*")) {
                                linea_inicio_comentario = num_linea_actual;
                                estado = this.tablaEstados.transicion(estado, str_carac_actual);
                                lexema = "";
                            } else {
                                Token = new token(lexema);
                                Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                                Token.setNumLinea(buffer.getNum_linea());
                                lei_adelantado = true;
                                str_carac_adelantado = str_carac_actual;
                                seguir = false;
                            }
                        }
                    }

                    break;
                }
                case 33: {

                    if (str_carac_actual == null) {
                        msg = errorLexico.construirError(7, linea_inicio_comentario);
                        throw new errorLexico(msg);
                    }
                    /*Inicio bloque control de excepciones*/
                    estado = tablaEstados.transicion(estado, str_carac_actual);
                    break;
                }
                case 34: {
                    /*Inicio bloque control de excepciones*/
                    if (str_carac_actual == null) {
                        nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                        msg = errorLexico.construirError(8, nro_linea_aux);
                        throw new errorLexico(msg);
                    }
                    /*Fin bloque control de excepciones*/
                    estado = tablaEstados.transicion(estado, str_carac_actual);
                    str_carac_actual = "";
                    str_carac_adelantado = "";
                    break;
                }
                case 35: {
                    /*Inicio bloque control de excepciones*/
                    if (str_carac_actual == null || hubo_salto_linea || !(str_carac_actual.equals("|"))) {
                        nro_linea_aux = num_linea_actual - this.buffer.getCant_saltos();
                        msg = errorLexico.construirError(8, nro_linea_aux);
                        throw new errorLexico(msg);
                    }
                    /*Fin bloque control de excepciones*/
                    lexema = lexema.concat(str_carac_actual);
                    estado = tablaEstados.transicion(estado, str_carac_actual);
                    break;
                }
                case 36: {
                    if (str_carac_actual != null) {
                        str_carac_adelantado = str_carac_actual;
                        lei_adelantado = true;
                    }
                    if (hubo_salto_linea) {
                        nro = num_linea_actual - this.buffer.getCant_saltos();
                    } else {
                        nro = num_linea_actual;
                    }
                    Token = new token(lexema);
                    Token.setNombre(palabrasEspeciales.obtenerNomToken(lexema));
                    Token.setNumLinea(nro);
                    seguir = false;
                    break;
                }
            }//del switch

        }//while

        return Token;
    }//getToken
}//class
